// Copyright (c) MatrixFramework. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using MatrixFramework.Keycloak.Abstractions.Services;
using MatrixFramework.Keycloak.Services;

namespace MatrixFramework.Keycloak.Extensions;

/// <summary>
/// 租户解析服务注册扩展
/// </summary>
public static class TenantResolverServiceCollectionExtensions
{
    /// <summary>
    /// 添加默认租户解析器
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configureProviders">配置租户提供程序</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddDefaultTenantResolver(
        this IServiceCollection services,
        Action<TenantProviderBuilder>? configureProviders = null)
    {
        // 注册HttpContextAccessor（如果还没有注册）
        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

        // 注册租户解析器
        services.AddSingleton<ITenantResolver>(provider =>
        {
            var logger = provider.GetService<Microsoft.Extensions.Logging.ILogger<DefaultTenantResolver>>();
            var tenantProviders = provider.GetServices<ITenantProvider>();
            return new DefaultTenantResolver(tenantProviders, logger);
        });

        // 配置租户提供程序
        if (configureProviders != null)
        {
            var builder = new TenantProviderBuilder(services);
            configureProviders(builder);
            builder.Build();
        }

        return services;
    }

    /// <summary>
    /// 添加HTTP头部租户提供程序
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="headerName">头部名称</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddHeaderTenantProvider(
        this IServiceCollection services,
        string headerName = "X-Tenant-ID")
    {
        services.AddSingleton<ITenantProvider>(provider =>
        {
            var httpContextAccessor = provider.GetRequiredService<IHttpContextAccessor>();
            var logger = provider.GetService<Microsoft.Extensions.Logging.ILogger<HeaderTenantProvider>>();
            return new HeaderTenantProvider(httpContextAccessor, headerName, logger);
        });

        return services;
    }

    /// <summary>
    /// 添加查询参数租户提供程序
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="parameterName">参数名称</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddQueryTenantProvider(
        this IServiceCollection services,
        string parameterName = "tenant")
    {
        services.AddSingleton<ITenantProvider>(provider =>
        {
            var httpContextAccessor = provider.GetRequiredService<IHttpContextAccessor>();
            var logger = provider.GetService<Microsoft.Extensions.Logging.ILogger<QueryTenantProvider>>();
            return new QueryTenantProvider(httpContextAccessor, parameterName, logger);
        });

        return services;
    }

    /// <summary>
    /// 添加子域名租户提供程序
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="excludeSubdomains">排除的子域名</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddSubdomainTenantProvider(
        this IServiceCollection services,
        string[]? excludeSubdomains = null)
    {
        services.AddSingleton<ITenantProvider>(provider =>
        {
            var httpContextAccessor = provider.GetRequiredService<IHttpContextAccessor>();
            var logger = provider.GetService<Microsoft.Extensions.Logging.ILogger<SubdomainTenantProvider>>();
            return new SubdomainTenantProvider(httpContextAccessor, excludeSubdomains, logger);
        });

        return services;
    }

    /// <summary>
    /// 添加配置租户提供程序
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="defaultTenantId">默认租户ID</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddConfigurationTenantProvider(
        this IServiceCollection services,
        string defaultTenantId = "default")
    {
        services.AddSingleton<ITenantProvider>(provider =>
        {
            var logger = provider.GetService<Microsoft.Extensions.Logging.ILogger<ConfigurationTenantProvider>>();
            return new ConfigurationTenantProvider(defaultTenantId, logger);
        });

        return services;
    }

    /// <summary>
    /// 添加常用租户解析配置（头部 + 查询参数 + 子域名 + 配置默认值）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="headerName">头部名称</param>
    /// <param name="parameterName">查询参数名称</param>
    /// <param name="excludeSubdomains">排除的子域名</param>
    /// <param name="defaultTenantId">默认租户ID</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddCommonTenantProviders(
        this IServiceCollection services,
        string headerName = "X-Tenant-ID",
        string parameterName = "tenant",
        string[]? excludeSubdomains = null,
        string defaultTenantId = "default")
    {
        return services
            .AddDefaultTenantResolver()
            .AddHeaderTenantProvider(headerName)
            .AddQueryTenantProvider(parameterName)
            .AddSubdomainTenantProvider(excludeSubdomains)
            .AddConfigurationTenantProvider(defaultTenantId);
    }
}

/// <summary>
/// 租户提供程序构建器
/// </summary>
public class TenantProviderBuilder
{
    private readonly IServiceCollection _services;

    public TenantProviderBuilder(IServiceCollection services)
    {
        _services = services;
    }

    /// <summary>
    /// 添加HTTP头部租户提供程序
    /// </summary>
    /// <param name="headerName">头部名称</param>
    /// <returns>构建器</returns>
    public TenantProviderBuilder AddHeader(string headerName = "X-Tenant-ID")
    {
        _services.AddHeaderTenantProvider(headerName);
        return this;
    }

    /// <summary>
    /// 添加查询参数租户提供程序
    /// </summary>
    /// <param name="parameterName">参数名称</param>
    /// <returns>构建器</returns>
    public TenantProviderBuilder AddQuery(string parameterName = "tenant")
    {
        _services.AddQueryTenantProvider(parameterName);
        return this;
    }

    /// <summary>
    /// 添加子域名租户提供程序
    /// </summary>
    /// <param name="excludeSubdomains">排除的子域名</param>
    /// <returns>构建器</returns>
    public TenantProviderBuilder AddSubdomain(string[]? excludeSubdomains = null)
    {
        _services.AddSubdomainTenantProvider(excludeSubdomains);
        return this;
    }

    /// <summary>
    /// 添加配置租户提供程序
    /// </summary>
    /// <param name="defaultTenantId">默认租户ID</param>
    /// <returns>构建器</returns>
    public TenantProviderBuilder AddConfiguration(string defaultTenantId = "default")
    {
        _services.AddConfigurationTenantProvider(defaultTenantId);
        return this;
    }

    /// <summary>
    /// 构建租户提供程序
    /// </summary>
    /// <returns>服务集合</returns>
    public IServiceCollection Build()
    {
        return _services;
    }
}